package com.whcoding.test.common.file;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 文件压缩、解压工具类。文件压缩格式为zip
 * @author Manager
 */
public class ZipUitls {
	/**
	 * 文件后缀名
	 */
	private static final String ZIP_FILE_SUFFIX = ".zip";

	/**
	 * 压缩文件
	 *
	 * @param resourcePath 源文件
	 * @param targetPath   目的文件,保存文件路径
	 */
	public static void zipFile(String resourcePath, String targetPath) {
		File resourcesFile = new File(resourcePath);
		File targetFile = new File(targetPath);

		//目的文件不存在，则新建
		if (!targetFile.exists()) {
			targetFile.mkdirs();
		}
		//文件名
		String targetName = resourcesFile.getName() + ZIP_FILE_SUFFIX;

		ZipOutputStream out = null;
		try {
			FileOutputStream outputStream = new FileOutputStream(targetPath + "//" + targetName);
			out = new ZipOutputStream(new BufferedOutputStream(outputStream));

			compressedFile(out, resourcesFile, "");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}


	/**创建文件夹
	 * @param out
	 * @param file
	 * @param dir
	 */
	private static void compressedFile(ZipOutputStream out, File file, String dir) {
		FileInputStream fis = null;
		try {
			//文件夹
			if (file.isDirectory()) {
				// 得到文件列表信息
				File[] files = file.listFiles();
				// 将文件夹添加到下一级打包目录
				out.putNextEntry(new ZipEntry(dir + "/"));

				dir = dir.length() == 0 ? "" : dir + "/";

				// 循环将文件夹中的文件打包
				for (int i = 0; i < files.length; i++) {
					// 递归处理
					compressedFile(out, files[i], dir + files[i].getName());
				}
			} else {    //如果是文件则打包处理
				fis = new FileInputStream(file);

				out.putNextEntry(new ZipEntry(dir));
				// 进行写操作
				int j = 0;
				byte[] buffer = new byte[1024];
				while ((j = fis.read(buffer)) > 0) {
					out.write(buffer, 0, j);
				}
				// 关闭输入流
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}



	// 压缩
	public static String compress(String str) throws IOException {
		if (str == null || str.length() == 0) {
			return str;
		}
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		GZIPOutputStream gzip = new GZIPOutputStream(out);
		gzip.write(str.getBytes());
		gzip.close();
		return out.toString("ISO-8859-1");
	}


	// 解压缩
	public static String uncompress(String str) throws IOException {
		if (str == null || str.length() == 0) {
			return str;
		}
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		ByteArrayInputStream in = new ByteArrayInputStream(str
				.getBytes(StandardCharsets.ISO_8859_1));
		GZIPInputStream gunzip = new GZIPInputStream(in);
		byte[] buffer = new byte[256];
		int n;
		while ((n = gunzip.read(buffer)) >= 0) {
			out.write(buffer, 0, n);
		}
		// toString()使用平台默认编码，也可以显式的指定如toString(&quot;GBK&quot;)
		return out.toString();
	}


}
